﻿Array.prototype.remove = function (from, to) {
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
}
Array.prototype.indexOf = function (substr, start) {
    var ta, rt, d = '\0';
    if (start != null) { ta = this.slice(start); rt = start; } else { ta = this; rt = 0; }
    var str = d + ta.join(d) + d, t = str.indexOf(d + substr + d);
    if (t == -1) return -1; rt += str.slice(0, t).replace(/[^\0]/g, '').length;
    return rt;
};
Array.prototype.lastIndexOf = function (substr, start) {
    var ta, rt, d = '\0';
    if (start != null) { ta = this.slice(start); rt = start; } else { ta = this; rt = 0; }
    ta = ta.reverse(); var str = d + ta.join(d) + d, t = str.indexOf(d + substr + d);
    if (t == -1) return -1; rt += str.slice(t).replace(/[^\0]/g, '').length - 2;
    return rt;
};
Array.prototype.replace = function (reg, rpby) {
    var ta = this.slice(0), d = '\0';
    var str = ta.join(d); str = str.replace(reg, rpby);
    return str.split(d);
};
Array.prototype.search = function (reg) {
    var ta = this.slice(0), d = '\0', str = d + ta.join(d) + d, regstr = reg.toString();
    reg = new RegExp(regstr.replace(/\/((.|\n)+)\/.*/g, '\\0$1\\0'), regstr.slice(regstr.lastIndexOf('/') + 1));
    t = str.search(reg); if (t == -1) return -1; return str.slice(0, t).replace(/[^\0]/g, '').length;
};



(function ($) {
    var ids = new Array();
    var values = new Array();
 
    jQuery.fn.attrFunctions = function (attrid, attrvalue) {


        if (attrid && attrvalue && attrvalue!="all") {
            ids.push(attrid);
            values.push(attrvalue);
        }
        else if (attrid&& !attrvalue) {
            var index = ids.indexOf(attrid);
            return values[index];
        }
        else if (attrid && attrvalue && attrvalue=="all") {
            var list=new Array();
            for(var i=0;i<ids.length;i++){ 
                list.push(values[i]);
            }
            return list;
        }
        return this;
    };
    jQuery.fn.findFunction=function(){
        var p,q
        for(var i=0;i<ids.length;i++){ 
                p=values[i]
                for(var n=0;n<ids.length;n++){ 
                    q=values[n]
                    ps=p.getStart()
                    qs=q.getStart()
                    pe=p.getEnd()
                    qe=q.getEnd()
                    if((i!=n &&  ps[0]==qs[0] && pe[0]==qe[0])||(qs[0]==qe[0])){
                        ids.splice(n, 1); 
                        values.splice(n, 1);
                        q.remove(); 
                    }
                }
         }
    
    }
    jQuery.fn.removeFunctions = function (attrid) {
       
         if (attrid) {
            var index = ids.indexOf(attrid);
            ids.splice(index, 1); 
            values.splice(index, 1); 
        }
        return this;
    };
    
})(jQuery);

function line($start,$end) {
    var start = $start;
    var end = $end;
    var $startDiv=$('<div style="position:absolute"></div>').css('background-color','black').appendTo('#container');
    var $middleDiv = $('<div style="position:absolute"></div>').css('background-color','black').appendTo('#container');
    var $endDiv = $('<div style="position:absolute"></div>').css('background-color','black').appendTo('#container');
    var ox_start;
    var oy_start;
    var ox_end;
    var oy_end;
    var startPoint;
    var endPoint;

    var size1, size2;
    var size = { x: size1, y: size2 };


    var findright=function($target){
        var a 
        var b
        var nods
        $target.find('.rightEar').each(
        function () {
            nods = this;
        });
        a = nods.offsetLeft + $target[0].offsetLeft + nods.offsetWidth / 2;
        b = nods.offsetTop + $target[0].offsetTop + nods.offsetHeight / 2;
        return{a:a,b:b,size:"v"};
    }
    var findlen = function ($start, $end) {



        var start = $start.get(0);
        var end = $end.get(0);


        var a = start.offsetLeft;
        var b = start.offsetTop;
        var x = end.offsetLeft;
        var y = end.offsetTop;

        var nod1, nod2, nods, node;
        var len, minlen;
        minlen = (a - x) * (a - x) + (b - y) * (b - y);
        $start.find('.leftEar, .topEar, .rightEar, .bottomEar').each(
        function () {
            nod1 = this;

            $end.find('.leftEar, .topEar, .rightEar, .bottomEar').each(
            function () {
                nod2 = this;

                nodh = Math.abs(nod1.offsetLeft + start.offsetLeft - nod2.offsetLeft - end.offsetLeft);
                nodv = Math.abs(nod1.offsetTop + start.offsetTop - nod2.offsetTop - end.offsetTop);
                len = nodh * nodh + nodv * nodv;
                if (len <= minlen) {
                    minlen = len;
                    nods = nod1;
                    node = nod2;
                }
            });
        });
        if (nods.className == "leftEar" || nods.className == "rightEar") { size.x = "v"; }
        if (nods.className == "topEar" || nods.className == "bottomEar") { size.x = "h"; }

        if (node.className == "leftEar" || node.className == "rightEar") { size.y = "v"; }
        if (node.className == "topEar" || node.className == "bottomEar") { size.y = "h"; }

        a = nods.offsetLeft + start.offsetLeft + nods.offsetWidth / 2;
        b = nods.offsetTop + start.offsetTop + nods.offsetHeight / 2;


        x = end.offsetLeft + node.offsetLeft + node.offsetWidth / 2;
        y = end.offsetTop + node.offsetTop + node.offsetHeight / 2;

        return { a: a, b: b, x: x, y: y, size1: size.x, size2: size.y };

    }


    var updatePositions = function () {
        var fl;
        var fr;
        if (start && end) { fl = findlen(start, end); }
        if (start && fl) {
            ox_start = fl.a;
            oy_start = fl.b;
        }
        else if(start && !fl ){
            fr=findright(start);
            ox_start = fr.a;
            oy_start = fr.b;
            size.x=fr.size;
            size.y=fr.size
        }
        else {
            ox_start = startPoint.x;
            oy_start = startPoint.y;
        }
        if (end && fl) {
            ox_end = fl.x;
            oy_end = fl.y;
        }
        else if(end && !fl ){
            fr=findright(end);
            ox_start = fr.a;
            oy_start = fr.b;
            size.x=fr.size;
            size.y=fr.size
        }
        else {
            ox_end = endPoint.x;
            oy_end = endPoint.y;
        }
    }
    var updateLines = function () {
        

        if (size.x == "v" && size.y == "v") {
            style = 1;
            //writenode();
            setline(ox_start, oy_start, (ox_start + ox_end) / 2, oy_start, $startDiv);
            setline((ox_start + ox_end) / 2, oy_start, (ox_start + ox_end) / 2, oy_end, $middleDiv);
            setline((ox_start + ox_end) / 2, oy_end, ox_end, oy_end, $endDiv);
            //writearrow()

        }
        else if (size.x == "h" && size.y == "h") {
            style = 2;
            //writenode();
            setline(ox_start, oy_start, ox_start, (oy_start + oy_end) / 2, $startDiv);
            setline(ox_start, (oy_start + oy_end) / 2, ox_end, (oy_start + oy_end) / 2, $middleDiv);
            setline(ox_end, (oy_start + oy_end) / 2, ox_end, oy_end, $endDiv);
            //writearrow()

        }
        else if (size.x == "h" && size.y == "v") {
            style = 3;
            //writenode();
            setline(ox_start, oy_start, ox_start, oy_end, $startDiv);
            setline(ox_start, oy_end, ox_end, oy_end, $middleDiv);
            setline(ox_end, oy_end, ox_end, oy_end, $endDiv)
            //writearrow()

        }
        else if (size.x == "v" && size.y == "h") {
            style = 4;
            //writenode();
            setline(ox_start, oy_start, ox_end, oy_start, $startDiv);
            setline(ox_end, oy_start, ox_end, oy_end, $middleDiv);
            setline(ox_end, oy_end, ox_end, oy_end, $endDiv)
            //writearrow()

        }

    }

    function setline(sx, sy, ex, ey, $line) {
        var Height;
        var Width;


        var Top;
        var Left;
        if (sx == ex) {

            if (sy > ey) {
                Height = sy - ey;
                Width = 2;


                Top = ey;
                Left = ex
            } else {
                Height = ey - sy;
                Width = 2;


                Top = sy;
                Left = sx;
            }

        } else if (sy == ey) {
            if (sx > ex) {
                Height = 2;
                Width = sx - ex;


                Top = ey;
                Left = ex;
            } else {
                Height = 2;
                Width = ex - sx;


                Top = sy;
                Left = sx;
            }

        }
        $line.css('width', Width).css('height', Height).css('top', Top).css('left', Left);
    }


    var draw = function () {
        updatePositions();
        updateLines();
    }
    var removeline=function(){
        $startDiv.remove();
        $endDiv.remove();
        $middleDiv.remove();
    }

    return {
        remove: function(){
            removeline()
            return this;
        },
        start: function ($start) {
            start = $start;
            draw();
            return this;
        },
        end: function ($end) {
            end = $end;
            draw();
            return this;
        },
        getStart: function () {
            return start;
        },
        getEnd: function () {
            return end;
        },
        updateStartPoint: function (startX, startY) {
            startPoint = { x: startX, y: startY };
            draw();
            return this;
        },
        updateEndPoint: function (endX, endY) {
            endPoint = { x: endX, y: endY };
            draw();
            return this;
        }
    }
}